import { create } from 'zustand';
import http from '@/utils/axios';

const modelList = [
    ["GPT 4o mini", "gpt-4o-mini"],
    ["o3 mini", "o3-mini"],
    ["Claude 3.7 Sonnet", "claude-3-7-sonnet-latest"],
    ["Claude 3.5 Sonnet", "claude-3-5-sonnet-latest"],
    ["Claude 3.5 Haiku", "claude-3-5-haiku-20241022"],
    ["Deepseek Reasoner", "deepseek-reasoner"],
    ["Deepseek Chat", "deepseek-chat"],
]

const useStore = create((set, get) => ({
    modelList: modelList,

    token: localStorage.getItem('token') || null,
    setToken: (value) => {
        localStorage.setItem('token', value);
        set({ token: value })
    },

    // isMobilView
    isMobileView: null,
    setIsMobileView: (value) => set({ isMobileView: value }),
    // sidebar visibility
    sidebarVisibility: null,
    setSidebarVisibility: (value) => set({ sidebarVisibility: value }),
    desktopViewSidebarVisibility: sessionStorage.getItem('desktopViewSidebarVisibility') ? JSON.parse(sessionStorage.getItem('desktopViewSidebarVisibility')) : true,
    toggleDesktopViewSidebarVisibility: () => set((state) => ({ desktopViewSidebarVisibility: !state.desktopViewSidebarVisibility })),
    mobileViewSidebarVisibility: sessionStorage.getItem('mobileViewSidebarVisibility') ? JSON.parse(sessionStorage.getItem('mobileViewSidebarVisibility')) : false,
    toggleMoblieViewSidebarVisibility: () => set((state) => ({ mobileViewSidebarVisibility: !state.mobileViewSidebarVisibility })),
    toggleSidebarVisibility: () => {
        const state = get();
        if (state.isMobileView) {
            const mobileViewSidebarVisibility = state.mobileViewSidebarVisibility
            state.toggleMoblieViewSidebarVisibility()
            sessionStorage.setItem('mobileViewSidebarVisibility', !mobileViewSidebarVisibility)

        } else {
            const desktopViewSidebarVisibility = state.desktopViewSidebarVisibility
            state.toggleDesktopViewSidebarVisibility()
            sessionStorage.setItem('desktopViewSidebarVisibility', !desktopViewSidebarVisibility)
        }
    },

    newChatPageSelectedModel: 'gpt-4o-mini', // defalut model
    setNewChatPageSelectedModel: (value) => set({ newChatPageSelectedModel: value }),

    currentDialogueUUID: null,
    setCurrentDialogueUUID: (value) => set({ currentDialogueUUID: value }),

    // data
    dialogueHistoryTags: [],
    setDialogueHistoryTags: (value) => set({ dialogueHistoryTags: value }),
    addDialogueHistoryTag: (value) => set((state) => ({ dialogueHistoryTags: [value, ...state.dialogueHistoryTags] })),
    // addDialogueHistoryTagList: (value) => set((state) => ({ dialogueHistoryTags: [...state.dialogueHistoryTags, ...value] })),
    deleteDialogueHistoryTag: (uuid) => set((state) => ({ dialogueHistoryTags: state.dialogueHistoryTags.filter((item, index) => item.uuid !== uuid) })),
    updateDialogueHistoryTag: (uuid, value) => set((state) => ({ dialogueHistoryTags: [value, ...state.dialogueHistoryTags.filter(item => item.uuid != uuid)] })),


    dialogues: {},
    addDialogue: (uuid, value) => set((state) => ({ dialogues: { ...state.dialogues, [uuid]: value } })),
    setDialogueModel: (uuid, value) => set((state) => ({ dialogues: { ...state.dialogues, [uuid]: { ...state.dialogues[uuid], current_model: value } } })),
    setDialogue: (uuid, value) => set((state) => ({ dialogues: { ...state.dialogues, [uuid]: { ...state.dialogues[uuid], dialogue_content_json: value } } })),
    deleteDialogueMessage: async (uuid, messageIndex) => set((state) => ({ dialogues: { ...state.dialogues, [uuid]: { ...state.dialogues[uuid], dialogue_content_json: state.dialogues[uuid].dialogue_content_json.filter((item, index) => messageIndex != index) } } })),
    updateDialogueMessage: (uuid, messageIndex, value) => set((state) => ({ dialogues: { ...state.dialogues, [uuid]: { ...state.dialogues[uuid], dialogue_content_json: state.dialogues[uuid].dialogue_content_json.map((item, index) => index === messageIndex ? value : item) } } })),
    // addMessageToDialogue: (uuid, value) => set((state) => ({ dialogues: { ...state.dialogues, [uuid]: { ...state.dialogues[uuid], dialogue_content_json: [...state.dialogues[uuid].dialogue_content_json, value] } } })),
    onRefreshDialogue: (uuid, messageIndex) => set((state) => ({ dialogues: { ...state.dialogues, [uuid]: { ...state.dialogues[uuid], dialogue_content_json: state.dialogues[uuid].dialogue_content_json.filter((item, index) => index <= messageIndex) } } })),



    // func
    syncDialogueToServer: async (uuid) => {
        const state = get();
        await http.put(`/dialogue/${uuid}`, state.dialogues[uuid])
    },
    handleChangeTagTitle: async (uuid, value) => {
        const state = get();
        let pre_titile = "";
        state.setDialogueHistoryTags(state.dialogueHistoryTags.map((item) => {
            if (item.uuid === uuid) {
                pre_titile = item.title;
                return { ...item, title: value }
            } else {
                return item;
            }
        }
        ));
        try {
            const response = await http.put("/dialogue_history/title/", { uuid: uuid, title: value })
        } catch (error) {
            state.setDialogueHistoryTags(state.dialogueHistoryTags.map((item) => item.uuid === uuid ? { ...item, item: pre_titile } : item))
        }

    },
    handleAutoGenerateTitle: async (uuid) => {
        const state = get();
        const generateTitlePrompt = "Only use few words to enerate a simple title based on the user's prompt. Just reply to the title without any other content. The user's prompt is:\n"
        const userPrompt = state.dialogues[uuid].dialogue_content_json[0].content;
        // console.log(userPrompt);

        const openAIAPIEndPoint = localStorage.getItem('generateTitleOpenAIAPIEndPoint');
        const openAIAPIKey = localStorage.getItem('generateTitleOpenAIAPIKey');
        let title = '';
        try {
            const response = await fetch(openAIAPIEndPoint + '/chat/completions', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'Authorization': `Bearer ${openAIAPIKey}`
                },
                body: JSON.stringify({
                    model: 'gpt-4o-mini',
                    messages: [{ role: 'user', content: generateTitlePrompt + userPrompt }], // 当前对话的上下文
                    stream: false
                })
            });
            const data = await response.json();
            title = data.choices?.[0]?.message?.content;
        } catch (error) {
            console.log(error.message);
            return;
        }
        // console.log(title);
        state.handleChangeTagTitle(uuid, title);
    },


    // LLM API
    creatingUUID: null,
    setCreatingUUID: (value) => set({ creatingUUID: value }),

    fetchingDialogue: {},
    setFetchingDialogue: (uuid, value) => set(state => ({ fetchingDialogue: { ...state.fetchingDialogue, [uuid]: value } })),

    handleOpenAILLMAPIFetch: async (uuid, model, prompt) => {
        const state = get();
        if (!model) {
            model = state.dialogues[uuid].current_model;
        }
        if (!prompt) {
            prompt = state.dialogues[uuid].dialogue_content_json;
        }
        const openAIAPIEndPoint = localStorage.getItem('openAIAPIEndPoint');
        const openAIAPIKey = localStorage.getItem('openAIAPIKey');
        let fullContent = ""; // 累积最终的回答内容

        if (!openAIAPIEndPoint) {
            state.setFetchingDialogue(uuid, 'Please set api endpoint.')
            return
        }
        if (!openAIAPIKey) {
            state.setFetchingDialogue(uuid, 'Please set api key.')
            return
        }

        state.setFetchingDialogue(uuid, '...')

        try {
            const response = await fetch(openAIAPIEndPoint + '/chat/completions', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'Authorization': `Bearer ${openAIAPIKey}`
                },
                body: JSON.stringify({
                    model: model,
                    messages: prompt, // 当前对话的上下文
                    stream: true
                })
            });

            const reader = response.body.getReader();
            const decoder = new TextDecoder("utf-8");

            let partialData = ""; // 用于存储不完整的 JSON 片段

            while (true) {
                const { done, value } = await reader.read();
                if (done) break;

                let chunk = decoder.decode(value, { stream: true });
                partialData += chunk;

                // 处理流数据，逐行解析
                let lines = partialData.split("\n");
                partialData = lines.pop(); // 可能是一个不完整的 JSON 片段，保留到下一次循环处理
                // console.log(lines);

                for (let line of lines) {
                    if (line.startsWith("data: ")) {
                        let jsonData = line.slice(6).trim();
                        if (jsonData === "[DONE]") {
                            // console.log("Stream finished.");
                            break;
                        }
                        try {
                            let parsed = JSON.parse(jsonData);
                            let content = parsed.choices?.[0]?.delta?.content || "";
                            fullContent += content;
                            // console.log("Received chunk:", content);

                        } catch (e) {
                            console.error("JSON parse error:", e);
                        }
                    }
                }
                state.setFetchingDialogue(uuid, fullContent);
                // console.log(fullContent);
            }


        } catch (error) {
            console.log(error);
            state.setFetchingDialogue(uuid, error.message);
            return;
        }

        const new_dialogue_content_json = [...state.dialogues[uuid].dialogue_content_json, { 'role': 'assistant', 'content': fullContent }]
        state.setDialogue(uuid, new_dialogue_content_json)
        state.setFetchingDialogue(uuid, null);
        await http.put(`/dialogue/${uuid}`, { current_model: model, dialogue_content_json: new_dialogue_content_json });
        const tag = await http.get(`/dialogue_history/${uuid}`);
        state.updateDialogueHistoryTag(uuid, tag.data);
    },
    isDialogueTagsLoading: true,
    dialogueTagsLoadingErrow: null,
    isLoadedAllDialogueTags: false,
    handleLoadMoreDialogueTags: async () => {
        let thisTimeloadedDataLength;
        const state = get();
        if (state.isLoadedAllDialogueTags) return 0;

        let last_modified_time = null;
        if (state.dialogueHistoryTags.length !== 0) {
            const lastTag = state.dialogueHistoryTags[state.dialogueHistoryTags.length - 1];
            last_modified_time = lastTag.last_modified_time;
            // console.log(last_modified_time);
        }
        try {
            const params = {
                last_modified_time: last_modified_time,
            }
            const response = await http.get('/dialogue_history/', { params });
            // console.log(response.data);

            set({ dialogueHistoryTags: [...state.dialogueHistoryTags, ...response.data] });
            thisTimeloadedDataLength = response.data.length
        } catch (error) {
            // setError(error.message);
            set({ dialogueTagsLoadingErrow: error.message })
        } finally {
            // setIsLoading(false);
            set({ isDialogueTagsLoading: false })
            if (thisTimeloadedDataLength === 0) {
                set({ isLoadedAllDialogueTags: true });
            }
            return thisTimeloadedDataLength
        }
    }

}));


export default useStore;
